package com.adamfass.tractorbeam;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.lwjgl.input.Controllers;

import com.adamfass.jmeutil.DebugGameState;
import com.jme.math.Vector3f;
import com.jme.system.DisplaySystem;

public class MainGameState extends DebugGameState {
  private final GameObjectManager gameObjectManager;
  private final GameFlow gameFlow;
  private final HashSet<GameUpdateLogic> gameUpdateLogicSet;
  private final HashSet<Controller> controllerSet;
  
  public MainGameState(GameFlow gameFlow) {
    super(false, true);
    
    gameObjectManager = new GameObjectManager();
    this.gameFlow = gameFlow;
    gameUpdateLogicSet = new HashSet<GameUpdateLogic>();
    controllerSet = new HashSet<Controller>();
    
    gameFlow.setUp(gameObjectManager, getRootNode(), getPhysicsSpace(), 
        gameUpdateLogicSet, controllerSet);
  }
  
  public void update(float timePerFrame) {
    super.update(timePerFrame);
    
    getRootNode().updateWorldBound();
    
    gameFlow.update(
        gameObjectManager, getRootNode(), getPhysicsSpace(), gameUpdateLogicSet);
    
    for (GameEntity gameEntity : gameObjectManager.getGameEntities()) {
      gameEntity.beforeUpdate();
    }
    
    for (GameEntity gameEntity : gameObjectManager.getGameEntities()) {
      gameEntity.update();
    }
    
    // Copy the set to a list so that instances can remove themselves from the set during
    // update.
    final ArrayList<GameUpdateLogic> gameUpdateLogicList = 
      new ArrayList<GameUpdateLogic>(gameUpdateLogicSet);
    for (GameUpdateLogic logic : gameUpdateLogicList) {
      logic.update(timePerFrame);
    }
    
    for (Controller controller : controllerSet) {
      controller.clearEventState();
    }
    
    getRootNode().updateRenderState();
    getRootNode().updateGeometricState(timePerFrame, true);
  }
}
